home *** CD-ROM | disk | FTP | other *** search
- /*
- File: RasterizeText.c
-
- Contains: QuickDraw GX to PostScript conversion code.
- File contains code necessary to convert text
- into bitmaps.
-
- File contains Routines for the Imaging Engine Shape Parts Drones.
-
- Version: Technology: Quickdraw GX 1.1.x
-
- Copyright: © 1994-1997 by Apple Computer, Inc., all rights reserved.
- */
-
- #include "GXToPSBuildConfig.h"
- #include <GXGraphics.h>
- #include "GXGraphicsPriv.h"
- #include <GXEnvironment.h>
- #include "GXToPostScript.h"
- #include "PublicPostScriptIE.h"
- #include "private.h"
- #include "PSIEResources.h"
- #include "GXErrors.h"
-
- #include "IOUtilities.h"
- #include "RDUtil.h"
-
-
- #ifndef SKIADOESNTDROPOUT
-
- #define kMinPenWidth 0x00018000 /* 1.5 units */
-
- /******************************************
-
- Function: FixUpTextFace
-
- Routine goes through the text face of a style
- and makes sure that all text faces will render
- properly into bitmaps.
-
- 1. Any thin frames are converted to hairlines.
-
- ********************************************/
- OSErr FixUpTextFace(TIEGlobalsHdl hIEGlobals, gxStyle aStyle, gxMapping *finalMapping);
- OSErr FixUpTextFace(TIEGlobalsHdl hIEGlobals, gxStyle aStyle, gxMapping *finalMapping)
- {
- OSErr status;
- long nLayers, idx;
- gxTextFace *theFace;
- gxFaceLayer *theLayer;
- Boolean changedFace;
- gxPoint penPoint;
-
- if (aStyle == nil)
- return(noErr);
-
- nLayers = GXGetStyleFace(aStyle, nil);
- if (nLayers == 0)
- return(noErr);
-
- status = PSSetWorkSpaceSize(hIEGlobals, sizeof(gxTextFace) + nLayers * sizeof(gxFaceLayer));
- nrequire(status, failed_faceSpace);
-
- HLock((*hIEGlobals)->hWorkSpace);
- theFace = (gxTextFace*)(*(*hIEGlobals)->hWorkSpace); // Hope gx graphics calls don't move memory.
- GXGetStyleFace(aStyle, theFace);
-
- /** Check each layer for thin hairlines and fix them if necessary **/
-
- changedFace = false;
-
- theLayer = theFace->faceLayer;
-
- for (idx = 0; idx < nLayers; ++idx, ++theLayer) {
-
- if ((theLayer->outlineFill == gxClosedFrameFill) || (theLayer->outlineFill == gxOpenFrameFill) ) {
-
- /** Get the pen width of the framed layer **/
-
- if (theLayer->outlineStyle != nil)
- penPoint.x = penPoint.y = GXGetStylePen(theLayer->outlineStyle);
- else
- penPoint.x = penPoint.y = ff(1);
-
- /** Run the pen width through the final mapping and see if it is too small **/
-
- MapPoints(finalMapping, 1, &penPoint);
- if (penPoint.x < 0) penPoint.x = -penPoint.x;
- if (penPoint.y < 0) penPoint.y = -penPoint.y;
-
- /** If it is too small, make it hairline **/
-
- if ( (penPoint.x < kMinPenWidth) || (penPoint.y < kMinPenWidth) ) {
-
- if (theLayer->outlineStyle == nil)
- theLayer->outlineStyle = GXNewStyle(); // we need a style to put a hairline on.
-
- GXSetStylePen(theLayer->outlineStyle, ff(0));
- changedFace = true;
-
- }//end if
-
- }//end if
-
- }//end for
-
- /** If any changes were made, put the changed text face back in the style **/
-
- if (changedFace)
- GXSetStyleFace(aStyle, theFace);
-
- /** Now dispose of any objects that were created by GXGetStyleFace **/
- theLayer = theFace->faceLayer;
-
- for (idx = 0; idx < nLayers; ++idx, ++theLayer) {
-
- if (theLayer->outlineStyle != nil)
- GXDisposeStyle(theLayer->outlineStyle);
-
- if (theLayer->outlineTransform != nil)
- GXDisposeTransform(theLayer->outlineTransform);
-
- }//end for
-
- status = PSReleaseWorkSpace(hIEGlobals);
- ncheck(status);
-
- failed_faceSpace:
- return(status);
-
- }//FixUpTextFace
-
- /******************************************
-
- Function: FixUpTextFaces
-
- Routine goes through the text faces of a shape
- and makes sure that all text faces will render
- properly into bitmaps.
-
- ********************************************/
- OSErr FixUpTextFaces(TIEGlobalsHdl hIEGlobals, gxShape theShape, gxMapping *finalMapping);
- OSErr FixUpTextFaces(TIEGlobalsHdl hIEGlobals, gxShape theShape, gxMapping *finalMapping)
- {
- OSErr status;
- gxShapeType theType;
- gxStyle aStyle, *pStyle;
- long runCount, idx;
- Handle workHandle;
-
- theType = GXGetShapeType(theShape);
- if (theType == gxLayoutType) {
-
- GXPrimitiveShape(theShape);
- theType = GXGetShapeType(theShape);
- if (theType == gxEmptyType)
- return(noErr);
-
- }//end if
-
- /**** Look at all of the styles and fix the text faces ****/
-
- aStyle = GXGetShapeStyle(theShape);
-
- /** Process the shape's root style **/
-
- status = FixUpTextFace(hIEGlobals, aStyle, finalMapping);
- nrequire(status, failed_fixFace);
-
- /** Process any styles in the geometry **/
-
- if (theType == gxGlyphType) {
-
- /** Allocate memory for the styles **/
-
- GXGetGlyphs(theShape, nil, nil, nil, nil, nil, &runCount, nil, nil);
- status = PSSetWorkSpaceSize(hIEGlobals, runCount * sizeof(gxStyle));
- nrequire(status, failed_workSpace);
- workHandle = (*hIEGlobals)->hWorkSpace;
- HLock(workHandle);
- pStyle = (gxStyle*)*workHandle;
-
- GXGetGlyphs(theShape, nil, nil, nil, nil, nil, &runCount, nil, pStyle);
-
- for (idx = 0; idx < runCount; ++idx) {
-
- status = FixUpTextFace(hIEGlobals, *pStyle++, finalMapping);
- nrequire(status, failed_fixFace1);
-
- }//end for
-
- failed_fixFace1:
- {
- OSErr saveStatus = PSReleaseWorkSpace(hIEGlobals);
- if (status == noErr)
- status = saveStatus;
- }
-
- }//end if
-
- failed_workSpace:
- failed_fixFace:
-
- return(status);
-
- }//FixUpTextFaces
-
- #endif
-
-
- /*****************************************
-
- Function: PSRasterizeShape
-
- Routine rasterizes a shape at device resolution
- for imaging by PostScript. We don't care about clips
- because the transform hiearchy has already been set up
- by the imaging engine before this routine even gets called,
- we just need to rasterize the right number of bits.
-
- hIEGlobals: Imaging Engine globals handle
- theShape: the shape to rasterize.
- parents: pointer to list of parent transforms. (nil means ignore, implies leave shape in device space)
- depth: number of parents. (pass zero if nil passed for above)
-
- *******************************************/
-
- OSErr PSRasterizeShape(TIEGlobalsHdl hIEGlobals, gxShape theShape, gxTransform *parents, long depth)
- {
- OSErr status;
- gxMapping aMapping;
- gxTag aTag;
- gxMapping *deviceMapping;
- gxMapping additionalMapping; // This mapping will be used by PS to concatenate with CTM for bitmap.
- gxMapping mapShapeThrough; // concatenation of all mappings for shape.
- gxTransform oldTransform; // shape's old transform.
- gxTransform newTransform;
- gxTransform *pTransform;
- long i;
-
- check( (parents != nil) || (depth == 0) );
-
- /* save the shape's transform before we muck around with it. */
-
- oldTransform = GXCloneTransform(GXGetShapeTransform(theShape));
-
-
- /* first map the shape through its own mapping */
-
- if (parents == nil) {
-
- ResetMapping(&mapShapeThrough);
-
- } else {
-
- GXGetShapeMapping(theShape, &mapShapeThrough);
-
-
- /** Now map it through the parents **/
-
- pTransform = &(parents[depth - 1]); // Point to shape's direct parents.
-
- for (i = 0; i < depth; ++i) {
-
- GXGetTransformMapping(*pTransform, &aMapping);
- MapMapping(&mapShapeThrough, &aMapping);
-
- --pTransform;
-
- }//end for
-
-
- /* Now apply the device mapping, but only if a transform list was passed in */
-
- deviceMapping = &( (*hIEGlobals)->deviceMapping );
- MapMapping(&mapShapeThrough, deviceMapping);
-
- /** Tag the shape with the rasterizedShapeTag, the tag contains the inverse of the mapping. **/
-
- InvertMapping(&additionalMapping, &mapShapeThrough);
- aTag = GXNewTag(rasterizedShapeTag, sizeof(gxMapping), &additionalMapping);
- GXSetShapeTags(theShape, rasterizedShapeTag, 0, 0, 1, &aTag);
- GXDisposeTag(aTag);
-
- }//end if
-
- #ifndef SKIADOESNTDROPOUT
- status = FixUpTextFaces(hIEGlobals, theShape, &mapShapeThrough);
- nrequire(status, failed_fixUpFaces);
- #endif
-
-
- /**** Now rasterize the shape ****/
-
- newTransform = GXNewTransform(); // Make a new trasnform with no clip
- GXSetTransformMapping(newTransform, &mapShapeThrough); // Give it the concatenation.
- GXSetShapeTransform(theShape, newTransform); // Give the shape this transform.
- GXDisposeTransform(newTransform); // Don't need our reference any more.
- GXSetShapeType(theShape, gxBitmapType); // Convert the shape to a bitmap.
-
- status = GXGetGraphicsError(nil);
- nrequire(status, failed_Rasterize);
-
- status = GXGetGraphicsError(nil);
- ncheck(status);
-
- failed_fixUpFaces:
- failed_Rasterize:
-
- /** Restore the shape's transform **/
-
- GXSetShapeTransform(theShape, oldTransform);
- GXDisposeTransform(oldTransform);
-
- return(status);
-
- }//PSRasterizeShape
-